package com.qububu.systemBase.exceptions;

import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import com.qububu.utils.SystemConstants;
import com.qububu.utils.SystemUtil;
import com.qububu.utils.SystemValidate;

/**
 * @author ZCW
 * @功能 全局异常处理
 * */
public class WholeExceptionHandler implements HandlerExceptionResolver {

	protected Logger log = LogManager.getLogger(this.getClass());
	
	/**
	 * @功能 异常统一处理
	 * 
	 * @详情 
	 * */
	public ModelAndView resolveException(HttpServletRequest req,
			HttpServletResponse resp, Object handler, Exception ex) {
		// TODO Auto-generated method stub
		
		Map<String, Object> parameters = new HashMap<String, Object>();  
        parameters.put("message", logErrorMessage(ex) );
		
		String hdAccep = req.getHeader("accept");
		
		System.out.println("Accept is ----" + hdAccep);
		
        String hdXReq = req.getHeader("X-Requested-With");
        
        if ((!SystemValidate.strIsNull(hdAccep) && hdAccep.indexOf("application/json") > -1)
        		|| (!SystemValidate.strIsNull(hdXReq) && hdXReq.indexOf("XMLHttpRequest") > -1) ) {//如果是异步请求
        	//JSON格式返回 
        	
        	Map<String, Object> errorMessageMap = new HashMap<String, Object>();
        	ObjectMapper objMapper = new ObjectMapper();
        	
        	errorMessageMap.put("result", SystemConstants.AJAX_FAILED_ALERT);
        	errorMessageMap.putAll(parameters);
        	
        	resp.setCharacterEncoding(req.getCharacterEncoding());
        	resp.setContentType("application/json");
        	
        	try {

        		// 将Map转换为json格式并通过resp.getWriter()输出
        		objMapper.writeValue(resp.getWriter(), errorMessageMap);
            } catch (IOException e) {
            	log.error("Exception happens when write error message to response.", e); 
            }
        	
        	return new ModelAndView();
        	
        } else {

        	return new ModelAndView(getNextPage(ex), parameters);
        }
	}
	
	/**
	 * @功能 将异常转换为错误信息
	 * */
	private String logErrorMessage(Exception ex) {
    	if (ex instanceof SessionTimeoutException) {
    		
    		return "您尚未登录或者登录信息超时，请先<a href=\"../user/login\">登录</a>后再操作";
    	} else {  // default exception message
        	
    		String exId = SystemUtil.createTimestamp();
        	
        	log.error("WholeExceptionHandler capture an exception with id " + exId, ex);
        	
    		return "消息ID：" + exId + " ， 详细信息：" + ex.getMessage();
    	}
    	
    }
	
	/**
	 * @功能 产生对应异常的返回页面
	 * */
	private String getNextPage(Exception ex) {
    	// 如果是登录的错误就到登录页面
    	// 如果是数据插入等的错误就提示服务器忙
    	// 如果是购买商品出现错误则需立即告知管理员
    	// 如果数据库处理发生错误出现错误则需立即告知管理员
		
    	if (ex instanceof SessionTimeoutException) {
    		// 跳转到主页并提示过期
    		return "redirect:/notice/info";
    	} else if (ex instanceof SQLException) { //如果是数据库异常
    		
    		return sqlExc(ex);
    	} else if (ex instanceof BuyException) { //如果是商品异常
    		
    		return buyExc(ex);
    	}  else if (ex instanceof PayException) { //如果是支付异常
    		
    		return payExc(ex);
    	} else {  // default exception page
    		// 普通异常的处理
    		String exId = SystemUtil.createTimestamp();
        	
        	log.error("WholeExceptionHandler capture an exception with id " + exId, ex);
    		
//    		return "redirect:friendly_prompt";
        	return "friendly_prompt";
    	}   	
    }
	
	
	/**
	 * @功能 对数据库异常做出处理
	 * */
	private String sqlExc(Exception ex) {
		
		// 先将异常信息发送给管理员
		
		String exId = SystemUtil.createTimestamp();
    	
    	log.error("|-- {SQL Exception} -- WholeExceptionHandler capture an exception with id " + exId, ex);
		
		return "friendly_prompt";
	}
	
	/**
	 * @功能 对商品进出购物车, 订单生成产生的异常进行处理
	 * */
	private String buyExc(Exception ex) {
		
		// 先将异常信息发送给管理员
		
		String exId = SystemUtil.createTimestamp();
		    	
		log.error("|-- {BUY Exception} -- WholeExceptionHandler capture an exception with id " + exId, ex);
		
		return "friendly_prompt";
	}
	
	/**
	 * @功能 对支付异常做出处理
	 * */
	private String payExc(Exception ex) {
		
		// 先将异常信息发送给管理员
		
		String exId = SystemUtil.createTimestamp();
		    	
		log.error("|-- {PAY Exception} -- WholeExceptionHandler capture an exception with id " + exId, ex);
		
		return "friendly_prompt";
	}

}
